home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / nn.zip / UNSHAR.C < prev    next >
C/C++ Source or Header  |  1989-06-28  |  5KB  |  181 lines

  1. /****************************************************************
  2.  * unshar.c: Unpackage one or more shell archive files
  3.  *
  4.  * Description:    unshar is a filter which removes the front part
  5.  *        of a file and passes the rest to the 'sh' command.
  6.  *        It understands phrases like "cut here", and also
  7.  *        knows about shell comment characters and the Unix
  8.  *        commands "echo", "cat", and "sed".
  9.  *
  10.  * HISTORY
  11.  *  27-July-88  Kim F. Storm (storm@texas.dk) Texas Instruments, Denmark
  12.  *    Adapted to :unshar command in nn
  13.  *    Added static to function declarations
  14.  *    Removed all unused functions, i.e. not useful as stand-alone pgm.
  15.  * 29-Jan-85  Michael Mauldin (mlm) at Carnegie-Mellon University
  16.  *    Created.
  17.  ****************************************************************/
  18.  
  19. #include "config.h"
  20.  
  21.  
  22. /****************************************************************
  23.  * position: position 'fil' at the start of the shell command
  24.  * portion of a shell archive file.
  25.  * Kim Storm: removed static variables
  26.  ****************************************************************/
  27.  
  28. unshar_position (fil)
  29. FILE *fil;
  30. {
  31.     char buf[BUFSIZ];
  32.     long pos, ftell ();
  33.     
  34.     /* Results from star matcher */
  35.     char res1[BUFSIZ], res2[BUFSIZ], res3[BUFSIZ], res4[BUFSIZ];
  36.     char *result[4];
  37.     
  38.     result[0] = res1, result[1] = res2, result[2] = res3, result[3] = res4 ;
  39.     
  40.     /*  rewind (fil);  */
  41.     
  42.     while (1) {
  43.     /* Record position of the start of this line */
  44.     pos = ftell (fil);
  45.     
  46.     /* Read next line, fail if no more */
  47.     if (fgets (buf, BUFSIZ, fil) == NULL) {
  48.         msg("no shell commands in file");
  49.         return (0);
  50.     }
  51.     
  52.     /* Bail out if we see C preprocessor commands or C comments */
  53.     if (stlmatch (buf, "#include")    || stlmatch (buf, "# include") ||
  54.         stlmatch (buf, "#define")    || stlmatch (buf, "# define") ||
  55.         stlmatch (buf, "#ifdef")    || stlmatch (buf, "# ifdef") ||
  56.         stlmatch (buf, "#ifndef")    || stlmatch (buf, "# ifndef") ||
  57.         stlmatch (buf, "/*"))
  58.         {
  59.         msg("file looks like raw C code, not a shar file");
  60.         return (0);
  61.         }
  62.     
  63.     /* Does this line start with a shell command or comment */
  64.     if (stlmatch (buf, "#")    || 
  65.         stlmatch (buf, ":") ||
  66.         stlmatch (buf, "echo ") ||
  67.         stlmatch (buf, "sed ") ||
  68.         stlmatch (buf, "cat ")) 
  69.     { 
  70.         fseek (fil, pos, 0);
  71.         return (1); 
  72.     }
  73.     
  74.     /* Does this line say "Cut here" */
  75.     if (smatch (buf, "*CUT*HERE*", result) ||
  76.         smatch (buf, "*cut*here*", result) ||
  77.         smatch (buf, "*TEAR*HERE*", result) ||
  78.         smatch (buf, "*tear*here*", result) ||
  79.         smatch (buf, "*CUT*CUT*", result) ||
  80.         smatch (buf, "*cut*cut*", result))
  81.     {
  82.         /* Read next line after "cut here", skipping blank lines */
  83.         while (1) {
  84.         pos = ftell (fil);
  85.         
  86.         if (fgets (buf, BUFSIZ, fil) == NULL) { 
  87.             msg("no shell commands after 'cut'");
  88.             return (0);
  89.         }
  90.         
  91.         if (*buf != '\n') break;
  92.         }
  93.         
  94.         /* 
  95.          * Win if line starts with a comment character of 
  96.          * lower case letter 
  97.          */
  98.         if (*buf == '#' ||
  99.         *buf == ':' ||
  100.         (('a' <= *buf) && ('z' >= *buf))) {
  101.         fseek (fil, pos, 0);
  102.         return (1);
  103.         }
  104.         
  105.         /* Cut here message lied to us */      
  106.         msg("invalid data after CUT line");
  107.         return (0);
  108.     }
  109.     }
  110. }
  111.  
  112. /*****************************************************************
  113.  * stlmatch  --  match leftmost part of string
  114.  *
  115.  * Usage:  i = stlmatch (big,small)
  116.  *    int i;
  117.  *    char *small, *big;
  118.  *
  119.  * Returns 1 iff initial characters of big match small exactly;
  120.  * else 0.
  121.  *
  122.  * HISTORY
  123.  * 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University
  124.  *      Ripped out of CMU lib for Rog-O-Matic portability
  125.  * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
  126.  *    Rewritten for VAX from Ken Greer's routine.
  127.  *
  128.  *  Originally from klg (Ken Greer) on IUS/SUS UNIX
  129.  *****************************************************************/
  130.  
  131. static int   stlmatch (big, small)
  132. char *small, *big;
  133. { register char *s, *b;
  134.   s = small;
  135.   b = big;
  136.   do
  137.   { if (*s == '\0')
  138.       return (1);
  139.   }
  140.   while (*s++ == *b++);
  141.   return (0);
  142. }
  143.  
  144. /*****************************************************************
  145.  * smatch: Given a data string and a pattern containing one or
  146.  * more embedded stars (*) (which match any number of characters)
  147.  * return true if the match succeeds, and set res[i] to the
  148.  * characters matched by the 'i'th *.
  149.  *****************************************************************/
  150.  
  151. static smatch (dat, pat, res)
  152. register char *dat, *pat, **res;
  153. { register char *star = 0, *starend, *resp;
  154.   int nres = 0;
  155.  
  156.   while (1)
  157.   { if (*pat == '*')
  158.     { star = ++pat;                  /* Pattern after * */
  159.       starend = dat;                  /* Data after * match */
  160.       resp = res[nres++];              /* Result string */
  161.       *resp = '\0';                  /* Initially null */
  162.     }
  163.     else if (*dat == *pat)              /* Characters match */
  164.     { if (*pat == '\0')              /* Pattern matches */
  165.     return (1);
  166.       pat++;                      /* Try next position */
  167.       dat++;
  168.     }
  169.     else
  170.     { if (*dat == '\0')              /* Pattern fails - no more */
  171.     return (0);                  /* data */
  172.       if (star == 0)                  /* Pattern fails - no * to */
  173.     return (0);                  /* adjust */
  174.       pat = star;                  /* Restart pattern after * */
  175.       *resp++ = *starend;              /* Copy character to result */
  176.       *resp = '\0';                  /* null terminate */
  177.       dat = ++starend;                  /* Rescan after copied char */
  178.     }
  179.   }
  180. }
  181.